<template>
  <div class="page-list common-list-container__v2" v-loading="pageLoading">

    <!-- 搜索 -->
    <div ref="tableHeaderContainer" class="page-list-search mar-b-12">
      <div class="page-list-search-form input-with-append-search">
        <el-input
          v-model.trim="searchParams.keyword"
          :placeholder="$t('im.imChat.components.mailChat.text5')"
          class="search-input"
          @keyup.enter.native="handleSearch">
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
          <el-button type="primary" slot="append" @click="handleSearch">
            {{ $t('common.base.search') }}
          </el-button>
        </el-input>

        <el-button class="ml_12" type="plain-third" @click="handleReset">
          {{ $t('common.base.reset') }}
        </el-button>

        <span class="advanced-search-btn pointer" @click.self="showAdvancedSearch">
          <i class="iconfont icon-filter"></i>
          {{ $t('component.advancedSearch.title') }}
        </span>
      </div>
    </div>

    <!-- 表格-->
    <div class="page-list-table">
      <div ref="tableDoContainer" class="page-list-table-toolbar">
        <!-- <el-dropdown trigger="click">
          <span class="el-dropdown-link cur-point">
            {{ $t('common.base.moreOperator') }}
            <i class="iconfont icon-fdn-select"></i>
          </span>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item>
              <div @click="handleExport(false)">{{ $t('common.base.export') }}</div>
            </el-dropdown-item>

            <el-dropdown-item>
              <div @click="handleExport(true)">{{ $t('common.base.exportAll') }}</div>
            </el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown> -->
        <div class="cur-point mar-l-24" @click="handleSelectColumn">
          {{ $t('common.base.choiceCol') }}
          <i class="iconfont icon-fdn-select"></i>
        </div>
      </div>

      <el-table
        v-table-style
        ref="tableRef"
        v-loading="listLoading"
        header-row-class-name="common-list-table-header__v2"
        :data="tableData"
        stripe
        border
        :row-key="getRowKey"
        @select="handleSelection"
        @select-all="handleSelection"
        @header-dragend="headerDragend"
        :class="['bbx-normal-list-box']"
        :height="tableContainerHeight">
        <template slot="empty">
          <BaseListForNoData v-show="!listLoading && !pageLoading" :notice-msg="$t('common.base.tip.noData')"></BaseListForNoData>
        </template>
        <el-table-column
          type="selection"
          width="48"
          align="center"
          fixed="left"
          :reserve-selection="true"
        />
        <template v-for="column in columns">
          <el-table-column
            v-if="column && column.show"
            show-overflow-tooltip
            :align="column.align"
            :key="column.field"
            :label="column.displayName"
            :min-width="column.minWidth"
            :prop="column.field"
            :sortable="column.sortable"
            :width="column.width"
            :fixed="column.fixLeft || false"
          >
            <template slot-scope="scope">
              <template v-if="column.fieldName === 'serialnumber'">
                <div class="link" @click="toDetail(scope.row)">
                  {{ scope.row.serialnumber || '' }}
                </div>
              </template>
              <template v-else-if="column.fieldName === 'sentDate'">
                {{ formatDate(scope.row.sentDate) }}
              </template>
              <template v-else-if="column.fieldName === 'customerName'">
                <div class="link" @click="openTabForCustomerView(scope.row.customerId)">
                  {{ scope.row.customerName || '' }}
                </div>
              </template>
              <template v-else>
                {{ $formatFormField(column, scope.row, 'attributeMap') }}
              </template>
            </template>
          </el-table-column>
        </template>
        <el-table-column fixed="right" :label="$t('common.fields.action.displayName')" width="100">
          <template slot-scope="scope">
            <div class="link" @click="toDetail(scope.row)">{{ $t('common.base.detail') }}</div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 表格E -->

      <!-- 分页 S -->
      <div ref="tableFooterContainer" class="table-footer bbx-normal-table-footer-10">
        <div class="list-info">
          <i18n path="common.base.table.totalCount">
            <span place="count" class="level-padding">{{ page.total }}</span>
          </i18n>
          <template v-if="multipleSelection && multipleSelection.length > 0">
            <i18n path="common.base.table.selectedNth">
              <span place="count" class="page-selected-count">{{ multipleSelection.length }}</span>
            </i18n>
            <span class="page-selected-count" @click="toggleClearSelection()">{{ $t('common.base.clear') }}</span>
          </template>
        </div>
        <el-pagination
          background
          @current-change="handlePageJump"
          @size-change="handleSizeChange"
          :page-sizes="[10, 20, 30, 40, 50, 100]"
          :page-size="page.pageSize"
          :current-page="page.pageNum"
          layout="prev, pager, next, sizes, jumper"
          :total="page.total">
        </el-pagination>
      </div>
    </div>

    <!-- 高级搜索框 -->
    <base-search-drawer
      :show.sync="visible"
      :storage-key="advancedColumnNumStorageKey"
      @reset="resetAdvancedSearchParams"
      @search="handleSearch"
      @changeWidth="setAdvanceSearchColumn"
      @getColumnNum="setAdvanceSearchColumn"
    >
      <base-search-panel
        ref="searchPanel"
        :column-num="columnNum"
        :fields="advanceSearchColumn"
        time-value-type="number"
      ></base-search-panel>
    </base-search-drawer>

    <!-- 导出 -->
    <base-export-group
      ref="exportRef"
      :alert="exportAlert"
      :columns="exportColumnList"
      :build-params="exportParamsBuild"
      :group="true"
      :validate="exportCountCheck"
      method="post"
      :action="imListExport"
    />

    <!-- 选择列 -->
    <biz-select-column
      ref="advanced"
      @save="saveColumnStatus"
      mode="contract"
    />

  </div>
</template>
<script>
/** vue */
import { defineComponent, reactive, toRefs, onMounted, nextTick, ref, set, computed } from 'vue';
/** model */
import Page from '@model/Page';
import StorageKeyEnum from '@model/enum/StorageKeyEnum.ts';
/** components */
import BaseSearchDrawer from 'packages/BaseSearchDrawer';
import BaseSearchPanel from 'packages/BaseSearchPanel';
import { Message } from 'element-ui';
/** util */
import { storageGet, storageSet } from '@src/util/storage';
import { toast } from '@src/util/platform'
import i18n from '@src/locales';
import { formatDate, useFormTimezone } from 'pub-bbx-utils'
import { getOssUrl } from '@src/util/assets'
import { jumpMailManagementDetail } from '@src/modules/im/tools/jump.js'
import { openTabForCustomerView } from '@src/util/business/openTab'
/* export & import */
import { imListExport } from '@src/api/Export';
/** fields */
import { getColumnFields,getAdvancedFields } from './fields'
/** api */
import * as ImApi from '@src/api/ImApi.js'
/** const */
const mailManagement_list_key = 'mailManagement_List'
const { disposeFormListViewTime } = useFormTimezone()

/** assets */
const noDataImage = getOssUrl('/no_data.png')

export default defineComponent({
  name: 'MailManagementList',
  components: {
    [BaseSearchDrawer.name]: BaseSearchDrawer,
    [BaseSearchPanel.name]: BaseSearchPanel,
  },
  setup() {
    const advanced = ref(null);
    const tableRef = ref(null);
    const exportRef = ref(null);
    const searchPanel = ref(null);

    const tableHeaderContainer = ref(null);
    const tableDoContainer = ref(null);
    const tableFooterContainer = ref(null);

    const state = reactive({
      noDataImage,
      pageLoading: false,
      page: new Page(),
      searchParams: {},
      listLoading: false,
      tableContainerHeight: '440px',
      columns: [],
      multipleSelection: [],
      columnNum: 1,
      advancedColumnNumStorageKey: StorageKeyEnum.MailManagementListAdvancedColumnNum,
      visible: false,
      imListExport,
    })

    const tableData = computed(() => {
      let columns = []
      state.columns.map(item => {
        let newItem = { ...item }
        const { formType, fieldName } = item
        // 生效日期和失效日期不更改，其他的更改formType
        if(formType === 'date' && (fieldName !== 'effectiveTime' && fieldName !== 'invalidTime')){
          newItem.formType = 'datetime'
        }
        columns.push(newItem)
      })
      return disposeFormListViewTime(state.page.list, columns)
    })

    // 选中数据id列表
    const selectedIds = computed(()=>{
      return state.multipleSelection.map(v=>v.id)
    })

    // 高级搜索字段
    const advanceSearchColumn = computed(()=>{
      const baseSearchFields = getAdvancedFields()
      return [...baseSearchFields]
    })

    // 导出字段
    const exportColumnList = computed(() => {
      const systemForm = state.columns.filter(v => v?.isSystem == 1)
      const systemInfo = {
        label: i18n.t('contract.setting.contractInformation'),
        value: 'systemChecked',
        columns: systemForm.map(item => {
          item.export = true;
          item.label = item.displayName;
          return item;
        }),
      };

      let column = [systemInfo].filter(item => {
        return item.columns && item.columns.length > 0;
      });

      return column;
    });
    
    const initSearchParams = () => {
      const localStorageData = getLocalStorageData();
      return {
        pageNum: 1,
        pageSize: localStorageData?.pageSize ?? 10,
        keyword: '',
      }
    }

    const init = async () => {
      
      try {
        state.pageLoading = true;

        state.searchParams = initSearchParams();

        await buildColumns();
      
        await getTableList(true)

        nextTick(() => {
          knowTableContainerHeight()
        })
      }catch(error){
        console.error(error);
      }finally {
        state.pageLoading = false;
      }
    }

    const handleSearch = async () => {
      getTableList()
    }

    const resetAdvancedSearchParams = (isSearch = true) => {
      if (searchPanel.value) {
        searchPanel.value.form = {}
        searchPanel.value.initFormVal()
      }
      isSearch && getTableList()
    }

    const handleReset = async () => {
      // 清空高级搜索参数
      resetAdvancedSearchParams(false)
      // 重置基本搜索参数
      state.searchParams = initSearchParams()

      getTableList()
    }

    const showAdvancedSearch = async () => {
      state.visible = true
    }

    const toDetail = async (row) => {
      jumpMailManagementDetail(row)
    }

    const getLocalStorageData = () => {
      const dataStr = storageGet(mailManagement_list_key, '{}');
      return JSON.parse(dataStr);
    }

    const saveDataToStorage = async (key, value) => {
      const data = getLocalStorageData();
      data[key] = value;
      storageSet(mailManagement_list_key, JSON.stringify(data));
    }

    // 表头改变
    const headerDragend = (newWidth, oldWidth, column, event) => {
      let ret = state.columns
        .map(item => {
          if (item.fieldName === column.property) {
            item.width = column.width;
          }
          return {
            field: item.field,
            show: item.show,
            width: item.width,
          };
        })
        
      modifyColumnStatus({ type: 'column', ret });
    };

    // 修改选择列设置
    const modifyColumnStatus = event => {
      let columns = event.data || [],
        colMap = columns.reduce(
          (acc, col) => (acc[col.field] = col) && acc,
          {}
        );
      state.columns.forEach(col => {
        let newCol = colMap[col.field];
        if (null != newCol) {
          set(col, 'show', newCol.show);
          set(col, 'width', newCol.width);
        }
      });

      saveColumnStatusToStorage();
    };

    // 保存选择列配置到本地
    const saveColumnStatusToStorage = () => {
      const localStorageData = getLocalStorageData();
      let columnsStatus = null;

      // 判断是否存储选择列
      const columnsList = state.columns.map(c => ({
        field: c.fieldName,
        show: c.show,
        width: c.width,
        fixLeft: c.fixLeft
      }));

      if (localStorageData.columnStatus) {
        localStorageData.columnStatus = columnsList;
        columnsStatus = localStorageData.columnStatus;
      } else {
        columnsStatus = columnsList;
      }

      saveDataToStorage('columnStatus', columnsStatus);
    };

    // 保存选择列
    const saveColumnStatus = event => {
      let columns = event.data || [];

      state.columns = [];
      nextTick(() => {
        state.columns = columns.slice();
        saveColumnStatusToStorage();
      });
      Message.success(i18n.t('common.base.saveSuccess'));
    };
    
    // 勾选checkbox
    const handleSelection = selection => {
      state.multipleSelection = selection;
      nextTick(() => {
        knowTableContainerHeight();
      });
    };

    const handleSelectColumn = () => {
      // 先把模板id去掉，不传到选择列组件里面，选择列组件对模板id做了处理
      let arr = state.columns.map(item => {
        delete item.templateId
        return item
      })
      advanced.value.open(arr);
    };

    // 清空选择项
    const toggleClearSelection = () => {
      state.multipleSelection = [];
      tableRef.value.clearSelection();
    };

    /**
     * @des 获取列表当前的可滚动高度
     */
    const knowTableContainerHeight = () => {
      let min = 440;
      try {
        let window_ = window.innerHeight;
        let header = tableHeaderContainer.value?.offsetHeight || 0;
        let do_ = tableDoContainer.value?.offsetHeight || 0;
        let footer = tableFooterContainer.value?.offsetHeight || 0;
        // eslint-disable-next-line no-mixed-operators
        min = window_ - header * 1 - do_ * 1 - footer * 1 - 12 * 2 - 16 * 2 - 4 - 12;
        min = min > 440 ? min : 440;
      } catch (error) {
        console.warn(error, 'error try catch');
      }
      state.tableContainerHeight = `${min}px`;
    };
    
    const buildSearchParams = () => {
      const advancedSearchParams = searchPanel.value?.buildParams() ?? {}
      return {
        ...state.searchParams,
        ...advancedSearchParams
      }
    }

    const getTableList = async (isInit = false) => {
      state.visible = false
      const params = buildSearchParams()
      try {
        !isInit && (state.listLoading = true)
        const res = await ImApi.getEmailList(params)
        if (res.code === 0) {
          res.data.list = res?.data?.list ?? []
          state.page = res.data || {};
        }
      } catch (error) {
        console.error(error, 'error try catch');
      } finally {
        state.listLoading = false
      }
    }

    // 页数改变时触发
    const handlePageJump = pageNum => {
      state.searchParams.pageNum = pageNum;
      getTableList();
    };

    // pageSize 改变时触发
    const handleSizeChange = pageSize => {
      saveDataToStorage('pageSize', pageSize);
      state.searchParams.pageSize = pageSize;
      state.searchParams.pageNum = 1;
      getTableList();
    };
    // 选择列排序
    const buildSortFields = (originFields = [], fieldsMap = {}) => {
      let fields = [];
      let unsortedFields = [];

      originFields.forEach(originField => {
        let { fieldName } = originField;
        let field = fieldsMap[fieldName];

        if (field) {
          let { index } = field;
          fields[index] = originField;
        } else {
          unsortedFields.push(originField);
        }
      });

      return fields.concat(unsortedFields);
    };

    // 构建表格选择列字段
    const buildColumns = async () => {

      // 获取缓存在本地的选择列配置
      const localStorageData = await getLocalStorageData();
      const columnStatus = localStorageData.columnStatus || [];

      const localColumns = columnStatus
        .map(i => (typeof i == 'string' ? { field: i, show: true } : i))
        .reduce((acc, col, currentIndex) => {
          acc[col.field] = {
            field: col,
            index: currentIndex,
          };
          return acc;
        }, {});
      
      let baseFields = getColumnFields();
      let customFields = [...baseFields];
      
      if (Array.isArray(columnStatus) && columnStatus.length > 0) {
        // 有本地缓存--列表排序
        customFields = buildSortFields(customFields, localColumns);
      }

      const columns = customFields.map(col => {
        // 选择列配置 是否勾选（显示）&宽度
        let show = col.show === true;
        let width = col.width;
        let localField = localColumns[col.field]?.field || null;
        let fixLeft = localField?.fixLeft || null;

        if (null != localField) {
          if (localField.width) {
            width = typeof localField.width == 'number'
              ? `${localField.width}px`
              : localField.width;
          }
          show = localField.show !== false;
        }

        col.show = show;
        col.width = width;
        col.minWidth = col.width || 150;
        col.type = 'column';
        col['fixLeft'] = fixLeft && 'left'
        return col;
      });

      state.columns = columns;
    };

    // 设置高级搜索展示列数
    const setAdvanceSearchColumn = command => {
      state.columnNum = Number(command);
    };

    // 导出 & 导出全部
    const handleExport = isExportAll => {
      let ids = [];
      let fileName = `${formatDate(
        new Date(),
        i18n.t('contract.list.handleExport.exportFileName', {date: 'YYYY-MM-DD'})
      )}`;

      if (!isExportAll) {
        if (!state.multipleSelection.length) {
          return toast(i18n.t('common.base.tip.exportNoChoice'), 'warning');
        }
        ids = selectedIds.value;
      }

      exportRef.value.open(ids, fileName, false);
    };

    // 导出提示
    const exportAlert = (result, params = {}) => {
      toast(result.message, result.status === 0 ? 'success' : 'error');
      toggleClearSelection();
    };

    // 构建导出参数
    const exportParamsBuild = (checkedMap, ids) => {
      let { systemChecked } = checkedMap || {};
      let checkArr = [...(systemChecked || [])];
      let exportAll = !ids || ids.length == 0;
      return {
        ...buildSearchParams(),
        id: ids,
        fieldList: checkArr || [],
        totalCount: exportAll ? state.page.total : selectedIds.value.length,
      };
    };

    /**
     * @description 检测导出条数
     * @return {String | null}
     */
    const exportCountCheck = (ids, max) => {
      let exportAll = !ids || ids.length == 0;

      return exportAll && state.page.total > max
        ? i18n.t('common.base.tip.exportLimit', { max })
        : null;
    };

    const getRowKey = row => {
      return row.id;
    };

    onMounted(() => {
      init();
    })

    return {
      advanced,
      tableRef,
      exportRef,
      searchPanel,
      tableHeaderContainer,
      tableDoContainer,
      tableFooterContainer,
      tableData,
      selectedIds,
      advanceSearchColumn,
      exportColumnList,
      ...toRefs(state),
      initSearchParams,
      handleSearch,
      resetAdvancedSearchParams,
      handleReset,
      showAdvancedSearch,
      saveColumnStatus,
      knowTableContainerHeight,
      handleSelection,
      headerDragend,
      toDetail,
      toggleClearSelection,
      handleSelectColumn,
      handlePageJump,
      handleSizeChange,
      setAdvanceSearchColumn,
      handleExport,
      exportAlert,
      exportParamsBuild,
      exportCountCheck,
      getRowKey,
      formatDate,
      openTabForCustomerView,
    }
  },
});
</script>
<style lang="scss" scoped>
.page-list {
  height: 100%;
  overflow: auto;
  padding: 12px;

  &-search {
    width: 100%;
    padding: 16px;
    background: #fff;
    box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.06);
    border-radius: 4px;

    &-form {
      display: flex;
      align-items: center;
      justify-content: flex-end;

      .search-input {
        width: 400px;
      }

      .advanced-search-btn {
        margin-left: 25px;
        @include fontColor;
      }
    }
  }

  &-table {
    background-color: #fff;
    border-radius: 4px;
    padding: 16px 16px 0;
    margin-top: 4px;

    &-toolbar {
      display: flex;
      justify-content: end;
      align-items: center;
      margin-bottom: 16px;
    }

    .link {
      color: $color-primary-light-6 !important;
      cursor: pointer;

      &:hover {
        text-decoration: underline;
      }
    }
  }

  .page-selected-count {
    @include fontColor();
    padding: 0 3px;
    width: 15px;
    text-align: center;
    cursor: pointer;
    font-size: 13px;
  }

  // 选中数据弹框样式
  .page-panel {
    .page-template-panel-btn {
      cursor: pointer;
      float: right;
      font-size: 14px;
      margin-right: 5px;

      &:hover {
        @include fontColor();
      }
    }

    &-selected {
      font-size: 14px;
      height: calc(100% - 51px);

      &-tip {
        padding-top: 80px;

        img {
          display: block;
          width: 240px;
          margin: 0 auto;
        }

        p {
          text-align: center;
          color: #9a9a9a;
          margin: 30px 0 0 0;
          line-height: 20px;
        }
      }
    }

    &-list {
      height: 100%;
      padding: 10px;
      overflow-y: auto;

      &-head {
        background-color: #f0f5f5;
        color: #333;
        font-size: 14px;

        &-name {
          padding-left: 10px;
          flex: 1;
          @include text-ellipsis;
        }
      }
    }

    .page-selected-row {
      display: flex;
      flex-flow: row nowrap;
      align-items: center;
      border-bottom: 1px solid #ebeef5;
      font-size: 13px;

      &:hover {
        background-color: #f5f7fa;

        .page-selected-delete {
          visibility: visible;
        }
      }

      .page-selected-sn {
        padding-left: 10px;
        width: 100%;
        @include text-ellipsis;
      }

      button.page-selected-delete {
        padding: 0;
        width: 36px;
        height: 36px;
        border: none;
        background-color: transparent;
        outline: none;
        color: #646b78;
        visibility: hidden;

        i {
          font-size: 14px;
        }

        &:hover {
          color: #e84040;
        }
      }
    }
  }
}
</style>
